package com.elitel.frame.base.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.elitel.common.utils.DateUtil;
import com.elitel.common.utils.UUIDUtil;
import com.elitel.frame.base.service.CfgFileParamService;
import com.elitel.frame.base.service.SysPrjServiceService;
import com.elitel.frame.main.dao.CfgFileParamMapepr;
import com.elitel.frame.main.entity.CfgFileParam;
import com.elitel.frame.main.entity.SysPrjservice;
import com.elitel.frame.main.entity.constant.TmpUser;
import com.elitel.frame.main.entity.vo.CfgFileParamVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文件服务Service
 *
 * @author mulis
 */
@Service
public class CfgFileParamServiceImpl implements CfgFileParamService {
    @Resource
    private CfgFileParamMapepr cfgFileParamMapepr;
    @Resource
    private SysPrjServiceService sysPrjServiceService;


    @Override
    public int deleteByPrimaryKey(String fileParamId) {
        return cfgFileParamMapepr.deleteByPrimaryKey(fileParamId);
    }

    @Override
    public int insert(CfgFileParam record) {
        record.setCreatedUser(TmpUser.ADMIN);
        record.setCreatedTime(new Date());
        record.setFileParamId(UUIDUtil.randomUUID());
        return cfgFileParamMapepr.insertSelective(record);
    }

    @Override
    public int insertSelective(CfgFileParam record) {
        record.setCreatedUser(TmpUser.ADMIN);
        record.setCreatedTime(new Date());
        record.setFileParamId(UUIDUtil.randomUUID());
        return cfgFileParamMapepr.insertSelective(record);
    }

    @Override
    public CfgFileParam selectByPrimaryKey(String fileParamId) {
        return cfgFileParamMapepr.selectByPrimaryKey(fileParamId);
    }

    @Override
    public int updateByPrimaryKeySelective(CfgFileParam record) {
        record.setUpdatedUser(TmpUser.ADMIN);
        record.setUpdatedTime(new Date());
        return cfgFileParamMapepr.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(CfgFileParam record) {
        return cfgFileParamMapepr.updateByPrimaryKeySelective(record);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CfgFileParamVo saveFileInfo(CfgFileParamVo param) {
        SysPrjservice sysPrjservice = this.saveServiceInfo(param);
        param.setServiceId(sysPrjservice.getGuid());
        this.saveCfgFileParam(param);
        return param;
    }

    /**
     * 保存文件服务参数信息
     *
     * @param param
     */
    private void saveCfgFileParam(CfgFileParamVo param) {
        String fileParamId = param.getFileParamId();
        CfgFileParam cfgFileParam = this.selectByPrimaryKey(fileParamId);
        // 设置变量信息
        this.setVarInfoVarInfoType(param);
        // 设置属性信息
        this.setAttrInfo(param);
        // 将文件状态初始化
        param.setFileStatus(0);

        // 数据入库
        if (cfgFileParam == null) {
            // 新增
            this.insertSelective(param);
        } else {
            // 更新
            this.updateByPrimaryKeySelective(param);
        }
    }

    private void setVarInfoVarInfoType(CfgFileParamVo param) {
        List<CfgFileParamVo.VarInfo> varList = param.getVarList();
        StringBuilder varInfo = new StringBuilder();
        StringBuilder varTypeInfo = new StringBuilder();
        for (CfgFileParamVo.VarInfo info : varList) {
            varInfo.append(info.getVarInfo()).append(",");
            varTypeInfo.append(info.getVarInfoType()).append(",");
        }
        param.setVarInfo(delEndChar(varInfo + "", ","));
        param.setVarInfoType(delEndChar(varTypeInfo + "", ","));

    }

    static String delEndChar(String tgt, String cha) {
        if (StringUtils.isNotEmpty(tgt)) {
            if (tgt.endsWith(cha)) {
                return tgt.substring(0, tgt.length() - 1);
            }
        }
        return tgt;
    }

    private void setAttrInfo(CfgFileParamVo param) {
        String attrInfo = JSONObject.toJSONString(this.getAttrMap(param), SerializerFeature.SortField);
        param.setAttrInfo(attrInfo);
    }

    @Override
    public List<CfgFileParamVo.Attr> getAttrList(CfgFileParamVo param) {
        Map<String, String> attrMap = this.getAttrMap(param);
        List<String> readonlyList = this.getAttrReadonlyList(param.getVarList());
        List<CfgFileParamVo.Attr> attrs = new ArrayList<>();
        attrMap.forEach((k, v) -> {
            CfgFileParamVo.Attr attr = new CfgFileParamVo.Attr();
            attr.setAttrName(k);
            attr.setAttrDesc(v);
            if (readonlyList.contains(k)) {
                attr.setReadOnlyFlag(true);
            } else {
                attr.setReadOnlyFlag(false);
            }
            attrs.add(attr);
        });
        return attrs;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delByGuId(String guid) {
        sysPrjServiceService.deleteByGuid(guid);
        cfgFileParamMapepr.deleteByServiceId(guid);
    }

    @Override
    public CfgFileParamVo getCfgInfo(String guid) {
        CfgFileParamVo res = new CfgFileParamVo();
        SysPrjservice byServiceGuid = sysPrjServiceService.getByServiceGuid(guid);
        if (byServiceGuid == null) return null;
        BeanUtils.copyProperties(byServiceGuid, res);
        CfgFileParam param = this.cfgFileParamMapepr.selectByServiceId(guid);
        BeanUtils.copyProperties(param, res);
        this.tranVarListAndAttrList(res);
        return res;
    }

    @Override
    public List<CfgFileParam> selectByFileStatus(Integer fileStatus) {
        return cfgFileParamMapepr.selectByFileStatus(fileStatus);
    }

    private void tranVarListAndAttrList(CfgFileParamVo res) {

        ArrayList<CfgFileParamVo.VarInfo> varInfoArrayList = new ArrayList<>();
        String varInfo = res.getVarInfo();
        String varInfoType = res.getVarInfoType();
        String attrInfo = res.getAttrInfo();
        JSONObject jsonObject = new JSONObject(true);
        if (StringUtils.isNotEmpty(attrInfo)) {
            jsonObject = JSONObject.parseObject(attrInfo, Feature.OrderedField);
        }


        if (StringUtils.isNotEmpty(varInfo) && StringUtils.isNotEmpty(varInfoType)) {
            String[] varInfos = varInfo.split(",");
            String[] varInfoTypes = varInfoType.split(",");
            if (varInfos.length == varInfoTypes.length) {
                for (int i = 0; i < varInfos.length; i++) {
                    CfgFileParamVo.VarInfo var = new CfgFileParamVo.VarInfo();
                    var.setVarInfo(varInfos[i]);
                    var.setVarInfoType(varInfoTypes[i]);
                    var.setVarInfoUnit(jsonObject.get(varInfos[i]) + "");
                    varInfoArrayList.add(var);
                }
            }
        }
        // 获取只读的属性
        List<String> readonlyList = this.getAttrReadonlyList(varInfoArrayList);
        ArrayList<CfgFileParamVo.Attr> attrList = new ArrayList<>();
        jsonObject.forEach((k, v) -> {
            CfgFileParamVo.Attr attr = new CfgFileParamVo.Attr();
            attr.setAttrName(k);
            attr.setAttrDesc(v + "");
            if (readonlyList.contains(k)) {
                attr.setReadOnlyFlag(true);
            } else {
                attr.setReadOnlyFlag(false);
            }
            attrList.add(attr);
        });
        res.setVarList(varInfoArrayList);
        res.setAttrList(attrList);
    }


    private List<String> getAttrReadonlyList(List<CfgFileParamVo.VarInfo> varInfoList) {
        List<String> res = new ArrayList<>();
        res.add("DT");
        res.add("DT_Unit");
        if (varInfoList != null && varInfoList.size() > 0) {
            res.addAll(varInfoList.stream().map(CfgFileParamVo.VarInfo::getVarInfo).collect(Collectors.toList()));
        }
        return res;
    }

    private LinkedHashMap<String, String> getAttrMap(CfgFileParamVo param) {
        LinkedHashMap<String, String> res = new LinkedHashMap<>(8);

        List<CfgFileParamVo.Attr> attrList = param.getAttrList();
        for (CfgFileParamVo.Attr attr : attrList) {
            res.put(attr.getAttrName(), attr.getAttrDesc());
        }
        if (param.getDt() != null) {
            res.put("DT", param.getDt() + "");
        }
        if (param.getDtUnit() != null) {
            res.put("DT_Unit", param.getDtUnit() + "");
        }
        List<CfgFileParamVo.VarInfo> varList = param.getVarList();

        for (CfgFileParamVo.VarInfo varInfo : varList) {
            res.put(varInfo.getVarInfo(), varInfo.getVarInfoUnit());
        }
        return res;
    }


    private SysPrjservice saveServiceInfo(CfgFileParamVo param) {
        SysPrjservice sysPrjservice = new SysPrjservice();
        sysPrjservice.setGuid(param.getServiceId());
        sysPrjservice.setServicecode(param.getServicecode());
        sysPrjservice.setPcode(param.getPcode());
        sysPrjservice.setServicename(param.getServicename());
        sysPrjservice.setServicetype(param.getServicetype());
        sysPrjservice.setRemark(param.getRemark());
        sysPrjServiceService.savePrjInfo(sysPrjservice);
        return sysPrjservice;
    }
}
